<?php

/**
 * This is the model class for table "{{account_token}}".
 *
 * The followings are the available columns in table '{{account_token}}':
 * @property integer $id
 * @property string $tokenDate
 * @property integer $tokenYear
 * @property integer $tokenMonth
 * @property string $note
 * @property integer $number
 * @property string $createTime
 * @property integer $createUserId
 * @property string $updateTime
 * @property integer $updateUserId
 *
 * The followings are the available model relations:
 * @property Project $project
 * @property User $updateUser
 * @property User $createUser
 * @property AccountTokenItem[] $items
 * @property MaterialExpense[] $materialExpenses
 */
class AccountToken extends CActiveRecord {
	/**
	 * Returns the static model of the specified AR class.
	 * @return AccountToken the static model class
	 */
	public static function model($className = __CLASS__) {
		return parent::model($className);
	}

	/**
	 * @return string the associated database table name
	 */
	public function tableName() {
		return '{{account_token}}';
	}

	public static function findYears() {
		return CHtml::listData(
			self::model()
				->findAll(array(
					'select' => 'tokenYear',
					'distinct' => true
				)), 'tokenYear', 'tokenYear');
	}
	/**
	 * @return array validation rules for model attributes.
	 */
	public function rules() {
		// NOTE: you should only define rules for those attributes that
		// will receive user inputs.
		return array(
			array(
				'number',
				'numerical',
				'integerOnly' => true,
//				'on' => array(
//					'insert'
//				)
			),
			array(
				'note',
				'length',
				'max' => 255
			),
			array(
				'number',
				'default',
				'value' => null,
				'on' => array(
					'insert'
				)
			),
			array(
				'tokenDate',
				'date',
				'format' => 'yyyy-MM-dd',
			),
			// The following rule is used by search().
			// Please remove those attributes that should not be searched.
			array(
				'id, tokenDate, tokenYear, tokenMonth, number, createTime, createUserId, updateTime, updateUserId',
				'safe',
				'on' => 'search'
			),
		);
	}

	public function behaviors() {
		return array(
			'AuditableBehavior' => array(
				'class' => 'components.db.AuditableBehavior',
				'attributes' => 'tokenDate, note'
			),
			'AuditStampBehavior' => array(
				'class' => 'components.db.AuditStampBehavior',
			),
		);
	}

	/**
	 * @return array relational rules.
	 */
	public function relations() {
		// NOTE: you may need to adjust the relation name and the related
		// class name for the relations automatically generated below.
		return array(
			'materialExpenses' => array(
				self::HAS_MANY,
				'MaterialExpense',
				'accountTokenId',
				'order' => 'expenseDate ASC',
			),
			'updateUser' => array(
				self::BELONGS_TO,
				'User',
				'updateUserId'
			),
			'createUser' => array(
				self::BELONGS_TO,
				'User',
				'createUserId'
			),
			'project' => array(
				self::BELONGS_TO,
				'AccountTokenProject',
				'projectId'
			),
			'items' => array(
				self::HAS_MANY,
				'AccountTokenItem',
				'tokenId'
			),
			'itemCount' => array(
				self::STAT,
				'AccountTokenItem',
				'tokenId'
			),
			'totalDebit' => array(
				self::STAT,
				'AccountTokenItem',
				'tokenId',
				'select' => 'sum(debit)',
			),
			'totalCredit' => array(
				self::STAT,
				'AccountTokenItem',
				'tokenId',
				'select' => 'sum(credit)',
			),
		);
	}

	/**
	 * @return array customized attribute labels (name=>label)
	 */
	public function attributeLabels() {
		return array(
			'id' => 'ID',
			'tokenDate' => '日期',
			'tokenYear' => '年',
			'tokenMonth' => '月',
			'note' => '备注',
			'number' => '编号',
			'createTime' => '创建时间',
			'createUserId' => '创建用户',
			'updateTime' => '更新时间',
			'updateUserId' => '更新用户',
		);
	}

	public function onBeforeSave($event) {
		if ($this->getIsNewRecord()) {
			$this->initDateNumber();
		} else {
			$timestamp = CDateTimeParser::parse($this->tokenDate, 'yyyy-MM-dd');
			$tokenMonth = intval(Yii::app()->dateFormatter->format('MM', $timestamp));
			$tokenYear = intval(Yii::app()->dateFormatter->format('yyyy', $timestamp));
			if ($this->tokenMonth != $tokenMonth || $this->tokenYear != $tokenYear) {
				$this->removeFromMonth($this->tokenYear, $this->tokenMonth, $this->number);
				$this->number = null;
				$this->initDateNumber();
			}
		}
		parent::onBeforeSave($event);
	}

	public function onBeforeDelete($event) {
		parent::onBeforeDelete($event);
		foreach ($this->items as $item) {
			$item->delete();
		}
	}

	public function onAfterDelete($event) {
		parent::onAfterDelete($event);
		$this->removeFromMonth($this->tokenYear, $this->tokenMonth, $this->number);
	}

	private function initDateNumber() {
		$timestamp = CDateTimeParser::parse($this->tokenDate, 'yyyy-MM-dd');
		$this->tokenMonth = Yii::app()->dateFormatter->format('MM', $timestamp);
		$this->tokenYear = Yii::app()->dateFormatter->format('yyyy', $timestamp);

		if (!($this->number > 0)) {
			$criteria = new CDbCriteria();
			$criteria->compare('tokenYear', $this->tokenYear);
			$criteria->compare('tokenMonth', $this->tokenMonth);
			if ($projectId = AccountTokenProject::getGlobalProjectId()) {
				$criteria->compare('projectId', $projectId);
			} else {
				$criteria->addInCondition('projectId', array(
						null
					));
			}
			$count = self::count($criteria);
			$this->number = $count + 1;
		} else {
			$criteria = new CDbCriteria();
			$criteria->compare('tokenYear', $this->tokenYear);
			$criteria->compare('tokenMonth', $this->tokenMonth);
			$criteria->compare('number', '>=' . $this->number);
			if ($projectId = AccountTokenProject::getGlobalProjectId()) {
				$criteria->compare('projectId', $projectId);
			} else {
				$criteria->addInCondition('projectId', array(
						null
					));
			}
			$existModels = self::findAll($criteria);
			foreach ($existModels as $existModel) {
				$existModel->number = $existModel->number + 1;
				$existModel->save();
			}
		}
	}

	private function removeFromMonth($year, $month, $number) {
		$criteria = new CDbCriteria();
		$criteria->compare('tokenYear', $year);
		$criteria->compare('tokenMonth', $month);
		$criteria->compare('number', '>' . $number);
		if ($projectId = AccountTokenProject::getGlobalProjectId()) {
			$criteria->compare('projectId', $projectId);
		} else {
			$criteria->addInCondition('projectId', array(
					null
				));
		}
		$existModels = self::findAll($criteria);
		foreach ($existModels as $existModel) {
			$existModel->number = $existModel->number - 1;
			$existModel->save();
		}
	}
	public function isBalanced() {
		return abs($this->totalCredit - $this->totalDebit) < 0.001;
	}
	public function getProjectName() {
		return $this->projectId ? $this->project->name : '公司';
	}

	/**
	 * Retrieves a list of models based on the current search/filter conditions.
	 * @return CActiveDataProvider the data provider that can return the models based on the search/filter conditions.
	 */
	public function search() {
		// Warning: Please modify the following code to remove attributes that
		// should not be searched.

		$criteria = new CDbCriteria;

		$criteria->compare('id', $this->id);
		$criteria->compare('tokenDate', $this->tokenDate, true);
		$criteria->compare('note', $this->note, true);
		$criteria->compare('number', $this->number);
		$criteria->compare('tokenYear', $this->tokenYear);
		$criteria->compare('tokenMonth', $this->tokenMonth);
		$criteria->compare('createTime', $this->createTime, true);
		$criteria->compare('createUserId', $this->createUserId);
		$criteria->compare('updateTime', $this->updateTime, true);
		$criteria->compare('updateUserId', $this->updateUserId);

		if ($projectId = AccountTokenProject::getGlobalProjectId()) {
			$criteria->compare('projectId', $projectId);
		} else {
			$criteria->addInCondition('projectId', array(
					null
				));
		}

		return new CActiveDataProvider($this,
			array(
				'criteria' => $criteria,
				'sort' => array(
					'defaultOrder' => array(
						'id' => true
					)
				),
			));
	}
}
